/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package byblos.util;

import byblos.negocio.NegocioExcecao;
import com.sun.image.codec.jpeg.ImageFormatException;
import com.sun.image.codec.jpeg.JPEGCodec;
import com.sun.image.codec.jpeg.JPEGEncodeParam;
import com.sun.image.codec.jpeg.JPEGImageEncoder;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Image;
import java.awt.RenderingHints;
import java.awt.image.BufferedImage;
import java.io.BufferedOutputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.Random;
import javax.imageio.ImageIO;
import javax.servlet.http.HttpServletRequest;
import javax.swing.ImageIcon;
import javax.swing.text.JTextComponent;
import org.joda.time.DateTime;
import org.vraptor.interceptor.UploadedFileInformation;

/**
 *
 * @author Diego
 */
public class Util {

    public static double getNumero(String texto) {
        if (texto == null || texto.equals("")) {
            return 0;
        }

        StringBuilder novoTexto = null;

        try {
            texto = texto.replaceAll(",", ".");

            texto = new StringBuilder(texto.toString()).reverse().toString();

            novoTexto = new StringBuilder();

            String faixa = "-.0123456789";

            boolean ponto = false;
            boolean traco = false;
            for (int i = 0; i < texto.length(); i++) {
                for (int j = 0; j < faixa.length(); j++) {
                    if (texto.charAt(i) == faixa.charAt(j)) {
                        if (texto.charAt(i) == '.') {
                            if (ponto) {
                                break;
                            } else {
                                ponto = true;
                            }
                        }

                        if (texto.charAt(i) == '-') {
                            if (traco) {
                                break;
                            } else {
                                traco = true;
                            }
                        }

                        novoTexto.append(texto.charAt(i));
                        break;
                    }
                }
            }

            if (novoTexto.length() == 0) {
                novoTexto.append('0');
            }
        } catch (NumberFormatException e) {
            novoTexto = new StringBuilder("0");
        }

        if (novoTexto == null || novoTexto.toString().equals(".")) {
            novoTexto = new StringBuilder("0");
        }

        novoTexto.reverse();

        double valor = 0;
        try {
            valor = Double.parseDouble(novoTexto.toString());
        } catch (NumberFormatException ex) {
        }
        return valor;

    }

    public static double getNumero(Object objeto) {
        if (objeto == null) {
            return 0;
        }
        if (objeto instanceof JTextComponent) {
            return getNumero(((JTextComponent) objeto).getText());
        }
        if (objeto instanceof String) {
            return getNumero((String) objeto);
        }
        if (objeto instanceof Double) {
            return (Double) objeto;
        }
        if (objeto instanceof Integer) {
            return (Integer) objeto;
        }
        return 0;
    }

    public static String getExtensaoArquivo(File arquivo) {
        String extensao = null;
        String s = arquivo.getName();
        int i = s.lastIndexOf('.');

        if (i > 0 && i < s.length() - 1) {
            extensao = s.substring(i + 1).toLowerCase();
        }
        return extensao;
    }

    public static int getRandom(int tamanhoLista) {
        return new Random().nextInt(tamanhoLista);
    }

    public static ImageIcon criarImageIcon(String caminho) {
        return criarImageIcon(Util.class.getResource(caminho));
    }

    public static ImageIcon criarImageIcon(URL url) {
        if (url != null) {
            return new ImageIcon(url);
        }
        return null;
    }

    public static byte[] getBytes(ImageIcon imagem) {
        return getBytes(imagem.getImage());
    }

    @SuppressWarnings(value = "all")
    public static byte[] getBytes(Image imagem) {
        byte[] bytes = null;

        if (imagem != null && imagem.getWidth(null) > 0 && imagem.getHeight(null) > 0) {
            try {
                BufferedImage bf = new BufferedImage(imagem.getWidth(null), imagem.getHeight(null), BufferedImage.TYPE_INT_RGB);
                Graphics g = bf.getGraphics();
                g.drawImage(imagem, 0, 0, null);
                g.dispose();
                ByteArrayOutputStream stream = new ByteArrayOutputStream();
                ImageIO.write(bf, "jpeg", stream);
                bytes = stream.toByteArray();
            } catch (IOException ex) {
                ex.printStackTrace();
            }
        } else {
            bytes = new byte[0];
        }

        return bytes;
    }

    /**  MÃ©todo para redimensionar imagensa qualidade varia de 0 a 100 */
    @SuppressWarnings(value = "all")
    public static File redimensionarImagem(String caminhoAplicacao, ImageIcon foto, int largura, int altura, int qualidade, boolean somenteMaior) {
        if (foto == null) {
            return null;
        }

        System.out.println("redimensionando");

        Image imagem = foto.getImage();
        // Calculos necessÃ¯Â¿Â½rios para manter as propoÃƒÂ§oes da imagem, conhecido
        // como "aspect ratio"

        double thumbRatio = (double) largura / (double) altura;
        int imageWidth = imagem.getWidth(null);
        int imageHeight = imagem.getHeight(null);
        double imageRatio = (double) imageWidth / (double) imageHeight;
        if (thumbRatio < imageRatio) {
            altura = (int) (largura / imageRatio);
        } else {
            largura = (int) (altura * imageRatio);
        }

        // Fim do cÃƒÂ¡lculo
        BufferedImage miniatura = new BufferedImage(largura, altura, BufferedImage.TYPE_INT_RGB);

        Graphics2D graphics2D = miniatura.createGraphics();

        graphics2D.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BILINEAR);

        graphics2D.drawImage(imagem, 0, 0, largura, altura, null);

        File arquivo = null;
        String caminho = caminhoAplicacao + "temp/" + nomeArquivoUnico("temporario") + ".jpg";

        try {
            arquivo = new File(caminho);
            System.out.println("largura da imagem " + imagem.getWidth(null));
            System.out.println("altura da imagem " + imagem.getHeight(null));
            if (imagem.getWidth(null) < largura && imagem.getHeight(null) < altura && somenteMaior) {
                System.out.println("-===============imagem.getWidth(null) < largura && imagem.getHeight(null) < altura && somenteMaior ========");
                return null;
            }
            BufferedOutputStream out = new BufferedOutputStream(new FileOutputStream(arquivo));
            JPEGImageEncoder encoder = JPEGCodec.createJPEGEncoder(out);
            JPEGEncodeParam param = encoder.getDefaultJPEGEncodeParam(miniatura);
            qualidade = Math.max(0, Math.min(qualidade, 100));
            param.setQuality((float) qualidade / 100.0f, false);
            encoder.setJPEGEncodeParam(param);
            encoder.encode(miniatura);
            out.close();
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (ImageFormatException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
//        foto = new ImageIcon(caminho);
        System.out.println("final redimensionamento");
        System.out.println("largura da imagem " + imagem.getWidth(null));
        System.out.println("altura da imagem " + imagem.getHeight(null));
//        arquivo.deleteOnExit();
//        return foto;
        return arquivo;
    }

    public static String salvarArquivo(HttpServletRequest request, String pasta,
            UploadedFileInformation containerArquivo, boolean salvarThumb, Dimension tamanhoNovo) {
        try {
            File arquivo = containerArquivo.getFile();
            String caminhoAplicacao = request.getRealPath("/");
            String nomeArquivo = Util.removerAcentos(containerArquivo.getFileName());
            System.out.println("fazendo update do arquivo " + nomeArquivo);
            System.out.println("tem tamanho novo " + tamanhoNovo != null);
            nomeArquivo = nomeArquivoUnico(nomeArquivo);
            String caminho = caminhoAplicacao + pasta + "/" + nomeArquivo;
            if (tamanhoNovo != null) {
                arquivo = redimensionarImagem(caminhoAplicacao, getImagemIcon(arquivo), (int) tamanhoNovo.getWidth(), (int) tamanhoNovo.getHeight(), 100, true);
                if (arquivo == null) {
                    arquivo = containerArquivo.getFile();
                }
            }
            System.out.println("===============================================");
            System.out.println("arquivo " + arquivo);
            System.out.println("caminho " + caminho);
            escrever(arquivo, caminho);
            if (deveSalvarThumb(salvarThumb, nomeArquivo)) {
                salvarThumbImagem(request, containerArquivo, nomeArquivo);
            }
            return "/byblos/" + pasta + "/" + nomeArquivo;
        } catch (Exception ex) {
            ex.printStackTrace();
            throw new NegocioExcecao("Não foi possível salvar o arquivo!", ex);
        }
    }

    private static String nomeArquivoUnico(String nomeArquivoAntigo) {
        return new DateTime().getSecondOfDay() + nomeArquivoAntigo;
    }

    private static boolean deveSalvarThumb(boolean salvarThumb, String nomeArquivo) {
        return (salvarThumb) && (nomeArquivo.toLowerCase().endsWith("jpg") ||
                nomeArquivo.toLowerCase().endsWith("jpeg"));
    }

    private static String salvarThumbImagem(HttpServletRequest request, UploadedFileInformation containerArquivo, String nomeArquivo) {
        try {
            String caminhoAplicacao = request.getRealPath("/");
            String caminho = caminhoAplicacao + "thumb/" + nomeArquivo;
            File arquivoThumb = redimensionarImagem(caminhoAplicacao, getImagemIcon(containerArquivo.getFile()), 100, 100, 100, true);
            System.out.println("caminhoThumb " + caminho);
            escrever(arquivoThumb, caminho);
            return caminho;
        } catch (Exception ex) {
            ex.printStackTrace();
            throw new NegocioExcecao("Não foi possível salvar a thumb!", ex);
        }
    }

    private static void escrever(File arquivo, String caminhoSaida) throws FileNotFoundException, IOException {
        FileInputStream entrada = new FileInputStream(arquivo);
        FileOutputStream saida = new FileOutputStream(new File(caminhoSaida));
        while (entrada.available() > 0) {
            byte[] bytes = new byte[entrada.available()];
            entrada.read(bytes);
            saida.write(bytes);
        }
        saida.flush();
        saida.close();
    }

    private static ImageIcon getImagemIcon(File arquivo) throws MalformedURLException {
        return new ImageIcon(arquivo.toURL());
    }

    public static String removerAcentos(String texto) {
        return RemoverdorAcentos.remover(texto);
    }

    private static class RemoverdorAcentos {

        static String acentuado = "ãâàáäêèéëîìíïõôòóöûúùüÃÂÀÁÄÊÈÉËÎÌÍÏÕÔÒÓÖÛÙÚÜçÇñÑ";
        static String semAcento = "aaaaaeeeeiiiiooooouuuuAAAAAEEEEIIIIOOOOOUUUUcCnN";
        static char[] tabela;
        

        static {
            tabela = new char[256];
            for (int i = 0; i < tabela.length; ++i) {
                tabela[i] = (char) i;
            }
            for (int i = 0; i < acentuado.length(); ++i) {
                tabela[acentuado.charAt(i)] = semAcento.charAt(i);
            }
        }

        private static String remover(final String s) {
            StringBuilder sb = new StringBuilder();
            for (int i = 0; i < s.length(); ++i) {
                char ch = s.charAt(i);
                if (ch < 256) {
                    sb.append(tabela[ch]);
                } else {
                    sb.append(ch);
                }
            }
            return sb.toString();
        }
    }
}
